// maak de linker global
var $bgpGameLinker = {};

$bgpGameLinker.load = function(moduleName, permutationsMap)
{
	// initialisatie
	var $wnd_0 = window, $doc_0 = document, gwtOnLoadFunc, bodyDone, base = '', metaProps = {}, values = [], providers = [], onLoadErrorFunc, propertyErrorFunc;
	if (!$wnd_0.__gwt_stylesLoaded)
	{
		$wnd_0.__gwt_stylesLoaded = {};
	}
	if (!$wnd_0.__gwt_scriptsLoaded)
	{
		$wnd_0.__gwt_scriptsLoaded = {};
	}

	// probeert de module te starten als het laden compleet is
	function maybeStartModule()
	{
		if (gwtOnLoadFunc && bodyDone)
		{
			gwtOnLoadFunc(onLoadErrorFunc, moduleName, base);
		}
	}

	// bepaalt de base dir van het script (hardcoded)
	function computeScriptBase()
	{
		base = "http://" + window.location.host + "/resources/" + moduleName + "/";
	}

	// loopt alle meta tags na voor properties etc.
	function processMetas()
	{
		var metas = document.getElementsByTagName('meta');
		for ( var i = 0, n = metas.length; i < n; ++i)
		{
			var meta = metas[i], name_0 = meta.getAttribute('name'), content;
			if (name_0)
			{
				if (name_0 == 'gwt:property')
				{
					content = meta.getAttribute('content');
					if (content)
					{
						var value, eq = content.indexOf('=');
						if (eq >= 0)
						{
							name_0 = content.substring(0, eq);
							value = content.substring(eq + 1);
						} else
						{
							name_0 = content;
							value = '';
						}
						metaProps[name_0] = value;
					}
				} else if (name_0 == 'gwt:onPropertyErrorFn')
				{
					content = meta.getAttribute('content');
					if (content)
					{
						try
						{
							propertyErrorFunc = eval(content);
						} catch (e)
						{
							alert('Bad handler "' + content + '" for "gwt:onPropertyErrorFn"');
						}
					}
				} else if (name_0 == 'gwt:onLoadErrorFn')
				{
					content = meta.getAttribute('content');
					if (content)
					{
						try
						{
							onLoadErrorFunc = eval(content);
						} catch (e)
						{
							alert('Bad handler "' + content + '" for "gwt:onLoadErrorFn"');
						}
					}
				}
			}
		}
	}

	// bepaal de waarde van een property uit de meta-tag of automagisch uit de propertyproviders
	function computePropValue(propName)
	{
		var value = providers[propName](), allowedValuesMap = values[propName];
		if (value in allowedValuesMap)
		{
			return value;
		}
		var allowedValuesList = [];
		for (var k in allowedValuesMap)
		{
			allowedValuesList[allowedValuesMap[k]] = k;
		}
		if (propertyErrorFunc)
		{
			propertyErrorFunc(propName, allowedValuesList, value);
		}
		throw null;
	}

	// property provider voor automatische bepaling van de user agent
	providers['user.agent'] = function()
	{
		var ua = navigator.userAgent.toLowerCase();
		var makeVersion = function(result)
		{
			return parseInt(result[1]) * 1000 + parseInt(result[2]);
		};
		if (ua.indexOf('opera') != -1)
		{
			return 'opera';
		} else if (ua.indexOf('webkit') != -1)
		{
			return 'safari';
		} else if (ua.indexOf('msie') != -1)
		{
			if (document.documentMode >= 8)
			{
				return 'ie8';
			} else
			{
				var result_0 = /msie ([0-9]+)\.([0-9]+)/.exec(ua);
				if (result_0 && result_0.length == 3)
				{
					var v = makeVersion(result_0);
					if (v >= 6000)
					{
						return 'ie6';
					}
				}
			}
		} else if (ua.indexOf('gecko') != -1)
		{
			var result_0 = /rv:([0-9]+)\.([0-9]+)/.exec(ua);
			if (result_0 && result_0.length == 3)
			{
				if (makeVersion(result_0) >= 1008)
					return 'gecko1_8';
			}
			return 'gecko';
		}
		return 'unknown';
	};

	// alle mogelijke waarden voor de user.agent property
	values['user.agent'] =
	{
	    gecko : 0,
	    gecko1_8 : 1,
	    ie6 : 2,
	    ie8 : 3,
	    opera : 4,
	    safari : 5
	};

	// bepaal de base dir van het script (hardcoded)
	computeScriptBase();

	// loop alle meta tags na voor properties etc.
	processMetas();

	// bepaal de strongname van de permutatie van deze browser
	var strongName;
	try
	{
		strongName = permutationsMap[computePropValue('user.agent')];
	} catch (e)
	{
		return;
	}

	// voor alle browsers geschikte, 'bulletproof' manier om te kijken of het document klaar is met laden
	var onBodyDoneTimerId;
	function onBodyDone()
	{
		if (!bodyDone)
		{
			bodyDone = true;
			maybeStartModule();
			if ($doc_0.removeEventListener)
			{
				$doc_0.removeEventListener('DOMContentLoaded', onBodyDone, false);
			}
			if (onBodyDoneTimerId)
			{
				clearInterval(onBodyDoneTimerId);
			}
		}
	}
	if ($doc_0.addEventListener)
	{
		$doc_0.addEventListener('DOMContentLoaded', function()
		{
			onBodyDone();
		}, false);
	}
	var onBodyDoneTimerId = setInterval(function()
	{
		if (/loaded|complete/.test($doc_0.readyState))
		{
			onBodyDone();
		}
	}, 50);

	// voeg een onScriptLoad methode toe, deze wordt aangeroepen aan het eind van de te laten module
	// en start de module als het document klaar is met laden
	$bgpGameLinker.load.onScriptLoad = function(pGwtOnLoadFunc)
	{
		gwtOnLoadFunc = pGwtOnLoadFunc;
		maybeStartModule();
	};

	// voegt een javascript tag aan een element toe
	function addJavascript(jsname, parent)
	{
		var e = document.createElement('script');
		e.setAttribute('type', 'text/javascript');
		e.setAttribute('src', jsname);
		parent.appendChild(e);
	}

	// voegt een link tag naar een stylesheet aan een element toe
	function addStylesheet(ssname, parent)
	{
		var e = document.createElement('link');
		e.setAttribute('rel', 'stylesheet');
		e.setAttribute('type', 'text/css');
		e.setAttribute('href', ssname);
		parent.appendChild(e);
	}

	// haal oude module weg
	var modulescripts = $doc_0.getElementById('modulescripts');
	var modulestyles = $doc_0.getElementById('modulestyles');
	modulescripts.innerHTML = "";
	modulestyles.innerHTML = "";

	// voeg de uitendelijk geselecteerde permutatie toe aan de div id=modulescripts van het document
	// aan het einde van die permutatie wordt de gwtOnLoadFunc pas meegegeven
	addStylesheet(base + 'style.css', modulestyles);
	addJavascript(base + strongName + '.cache.js', modulescripts);
};
